﻿#include "CtrlWidget.h"

#include "ui_CtrlWidget.h"
#include "ui_MainWindow.h"

CtrlWidget::CtrlWidget(QWidget *parent)
    : QWidget(parent), ui(new Ui::CtrlWidget), m_parent(static_cast<MainWindow *>(parent->parentWidget()))
{
    ui->setupUi(this);

    QObject::connect(ui->applyButton, SIGNAL(clicked(void)), this, SLOT(apply()));
    QObject::connect(ui->cancelButton, SIGNAL(clicked(void)), this, SLOT(cancel()));
    QObject::connect(ui->removeButton, SIGNAL(clicked(void)), this, SLOT(remove()));
    QObject::connect(ui->deleteButton, SIGNAL(clicked(void)), this, SLOT(delete_()));
}

CtrlWidget::~CtrlWidget()
{
    delete ui;
}

void CtrlWidget::initialize()
{
    ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);  // 禁用编辑
    ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); // 设置选择行为为整行
}

void CtrlWidget::update_widget()
{
    int row = m_parent->m_selected.size();
    ui->tableWidget->setRowCount(row);

    std::string continuity = ui->G0->isChecked() ? "G0" : (ui->G1->isChecked() ? "G1" : "G2");
    std::string constraint = ui->inner->isChecked() ? "内部" : (ui->boundary->isChecked() ? "边界" : "引导线");

    // 设置表头
    QStringList headers;
    headers << "选取"
            << "连续性"
            << "约束"
            << "支持面";
    ui->tableWidget->setHorizontalHeaderLabels(headers);

    const auto &shapes = m_parent->m_selected;
    for (int i = 0; i < shapes.size(); i++)
    {
        // 限制 id 范围
        int id = shapes[i].HashCode(100);

        std::string type;
        if (shapes[i].ShapeType() == TopAbs_EDGE)
            type = "曲线";
        else if (shapes[i].ShapeType() == TopAbs_FACE)
            type = "曲面";
        else
            type = "未知";

        std::string curve = type + std::to_string(id);
        ui->tableWidget->setItem(i, 0, new QTableWidgetItem(curve.c_str()));
        if (ui->tableWidget->item(i, 1) == nullptr)
            ui->tableWidget->setItem(i, 1, new QTableWidgetItem(continuity.c_str()));
        if (ui->tableWidget->item(i, 2) == nullptr)
            ui->tableWidget->setItem(i, 2, new QTableWidgetItem(constraint.c_str()));
    }
}

void CtrlWidget::deal_with_event()
{
    // 记录选中的拓扑
    auto slist = m_parent->occ_widget()->selected_shapes();
    if (!slist.empty())
    {
        // 重复选取则移除
        TopoDS_Shape sh = slist[0];
        auto &shapes = m_parent->m_selected;
        auto it = std::find(shapes.begin(), shapes.end(), sh);
        if (it != shapes.end())
        {
            shapes.erase(it);
            update_widget();
            return;
        }

        // 否则添加
        shapes.push_back(sh);

        // 注意先刷新表格再选中
        update_widget();
        ui->tableWidget->selectRow(ui->tableWidget->rowCount() - 1);
    }
}

void CtrlWidget::apply()
{
}

void CtrlWidget::cancel()
{
    m_parent->m_selected.clear();
    ui->tableWidget->clear();
    m_parent->show_message("放弃命令");
    update_widget();
}

void CtrlWidget::remove()
{
    QModelIndexList selectedIndexes = ui->tableWidget->selectionModel()->selectedIndexes();

    // 删除选中的行
    if (!selectedIndexes.isEmpty())
    {
        int row = selectedIndexes.at(0).row();
        m_parent->m_selected.erase(m_parent->m_selected.begin() + row);
        ui->tableWidget->removeRow(row);

        update_widget();
        
        // 选中上一行
        ui->tableWidget->selectRow(row - 1);
    }
}

void CtrlWidget::delete_()
{
    QModelIndexList selectedIndexes = ui->tableWidget->selectionModel()->selectedIndexes();

    // 删除选中的行（只删除独立的 shape，子拓扑不删除）
    if (!selectedIndexes.isEmpty())
    {
        int row = selectedIndexes.at(0).row();
        auto &shapes = m_parent->m_selected;
        auto it = std::find(m_parent->m_shapes.begin(), m_parent->m_shapes.end(), shapes[row]);
        if (it != m_parent->m_shapes.end())
        {
            m_parent->m_shapes.erase(it);
            shapes.erase(shapes.begin() + row);

            ui->tableWidget->removeRow(row);
            ui->tableWidget->selectRow(row - 1);
        }

        update_widget();
    }

    // 删除选中的点云
    auto cloud = m_parent->occ_widget()->selected_point_cloud();
    auto it = std::find(m_parent->m_clouds.begin(), m_parent->m_clouds.end(), cloud);
    if (it != m_parent->m_clouds.end())
        m_parent->m_clouds.erase(it);

    m_parent->occ_widget()->update_interactive_context();
}
